Pseudorandom Permutations

A pseudorandom permutation (PRP) is a specific type of pseudorandom function (PRF).

Definition: Pseudorandom Permutation (PRP)

A pseudorandom permutation is a pseudorandom function which satisfies the following properties:

  • The output length is the same as the input length , i.e. .
  • The function is a permutation of , i.e. the function is bijective.
  • The function is reversible, i.e. there is an efficient algorithm such that for all .

Definition Breakdown

A pseudorandom permutation is a subtype of a pseudorandom function where the output length matches the input length . Furthermore, a PRP is a bijection which maps each binary string of length to a single binary string, also of length . Finally, the PRP must be reversible in the sense that there is an efficient algorithm which can recover the input that was passed to the PRP in order to obtain a specific output.

The input/output length is often called the block length.

Pseudorandom permutation are useful in the construction of block ciphers because they have inputs and outputs of the same length.

Theoretical Implementation - PRPs from PRFs

Since PRPs are a subtype of PRFs, it is not unreasonable to believe that the latter can be used to construct the former. In particular, three pseudorandom functions with equal-length inputs and outputs can be used to construct a pseudorandom permutation whose block length is twice that of the original function, i.e .

Note

This is purely a theoretical construct used solely for illustrative purposes and it is not utilised in practice.

To construct such a PRP from three such PRFs, we use several rounds of the so-called Feistel transformation. Our PRP begins by parsing its input as two separate strings by splitting it in half, i.e. and . It then invokes and XORs its output with to produce the value . Subsequently, the PRP calls the next pseudorandom function on and XORs its output with to produce the value . The penultimate step is to produce the value by invoking the third pseudorandom function on and XOR-ing its output with . Finally, our PRP outputs the concatenation of and .

#![allow(unused)]
fn main() {
fn PRP(input: str[2S]) -> str[2S]
{
	let x1 = input[0..S];
	let x2 = input[S..];
	
	let y1 = xor(f1(x2), x1);
	let y2 = xor(f2(y1), x2);
	
	let z = xor(f3(y2), y1);
	
	return z + y2;
}
}

All operations used are efficient and they are also used a fixed number of times for any input which means that this PRP is indeed efficient. Moreover, it is easily reversible simply by executing these operations in reverse order.

#![allow(unused)]
fn main() {
fn RevPRP(input: str[2S]) -> str[2S]
{
	let z = input[0..S];
	let y2 = input[S..];
	
	let y1 = xor(f3(y2), z);
	
	let x2 = xor(f2(y1), y2);
	let x1 = xor(f1(x2), y1);
	
	return x1 + x2;
}
}

The more arduous task is proving that this permutation is indeed pseudorandom.

Proof of Pseudorandomness

TODO!

Pseudorandom Permutation Generator (PRPG)

Since PRPs are a subtype of PRFs and pseudorandom function generators (PRFGs) are a way to produce pseudorandom functions, we can reason about a restricted subtype of PRFGs which produce pseudorandom permutations.

Definition: Pseudorandom Permutation Generator (PRPG)

A pseudorandom permutation generator is a pseudorandom function generator which takes a seed and outputs a pseudorandom permutation over .

Definition Breakdown

A PRPG is a PRFG for pseudorandom permutations. The block length of the PRPs produced by a given PRPG is the same as the length of the seed used for it.

As with PRFs, it is common to denote the function output by a PRPG for some particular seed as .

Similarly to PRFGs, it is important to remember that the output of a PRPG is still a function. Nevertheless, this did not stop mathematicians' folly before and it certainly will not stop it now - it is common to see a PRPG as a two input algorithm that takes a seed and an input data block and acts like a pseudorandom permutation . In this case, internally obtains the function from the seed and then passes it the data block . Finally, the PRPG returns the output of the permutation .

#![allow(unused)]
fn main() {
fn PRPG(seed: str[S], idb: str[S]) -> str[S] {
	let PRP = get_prp_from_seed(seed);
	return PRP(idb);
}
}